//
//  AJPushService.m
//  AJPushSDK
//
//  Created by Black on 2021/2/2.
//  Copyright © 2018 anji-plus 安吉加加信息技术有限公司 http://www.anji-plus.com. All rights reserved.
//

#import "AJPushService.h"
#import "AJPushDeviceInfo.h"
// 引入 JPush 功能所需头文件
#import <JPush/JPUSHService.h>
// iOS10 注册 APNs 所需头文件
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif

#ifdef DEBUG
# define AJDLog(fmt, ...) NSLog((@"[函数名:%s]" "[行号:%d]" fmt),__FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
# define AJDLog(...);
#endif

NSString *const kAJPushServiceCustomMessageNotification = @"kAJPushServiceCustomMessageNotificationKey";//自定义消息
NSString *const kAJPushServiceNoticeBarMessageNotification = @"kAJPushServiceNoticeBarMessageNotificationKey";//通知栏消息
NSString *const kAJPushServiceInnerMessageNotification = @"kAJPushServiceInnerMessageNotificationKey";//内部消息提醒

typedef enum {
    AJPushTypeApplication, //外部消息启动app获取
    AJPushTypeOuter,//app进入后台，消息栏唤醒
    AJPushTypeInner, //app前台消息提醒
    AJPushTypeCustomer //自定义消息
} AJPushType;

@interface AJPushService ()<JPUSHRegisterDelegate>
@end

@implementation AJPushService {
    BOOL _isProduction;
    NSString *_appKey;
    NSString *_ajAppKey;
    NSString *_channel;
    NSString *_baseUrl;
}

static AJPushService *__service;
+ (instancetype)shareService {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        __service = [[super allocWithZone:NULL] init];;
    });
    return __service;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone{
    return [self shareService];
}

- (void)registerJPushOption:(NSDictionary *)launchingOption
                 appKey:(NSString *)appKey
                ajAppKey:(NSString *)ajAppKey
                channel:(NSString *)channel
       apsForProduction:(BOOL)isProduction {

    _appKey = appKey;
    _ajAppKey = ajAppKey;
    _channel = channel;
    _isProduction = isProduction;
    [self initAPNS];
    [self initJPushWithOptions:launchingOption];
    [self initLocationNotification];
}
- (void)registerDeviceToken:(NSData *)deviceToken withUrl:(nullable NSString *)baseUrl {
    _baseUrl = baseUrl;
    if (_baseUrl == nil) {
        _baseUrl = @"http://appsp.test.anji-plus.com";
    }
    [JPUSHService registerDeviceToken:deviceToken];
    //获取registrationID
    [JPUSHService registrationIDCompletionHandler:^(int resCode, NSString *registrationID) {
        AJDLog(@"++ registrationID: %@", registrationID);
        [self requestWithRegistrationId:registrationID];
        self.registrationID = registrationID;
    }];
}

- (BOOL)isProduction {
    return _isProduction;
}

# pragma mark- 初始化极光服务
//添加初始化 APNs 代码
- (void)initAPNS {
    //notice: 3.0.0 及以后版本注册可以这样写，也可以继续用之前的注册方式
    JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
    if (@available(iOS 12.0, *)) {
        entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound|JPAuthorizationOptionProvidesAppNotificationSettings;
    } else {
        entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound;
    }
    [JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
}

//初始化极光服务
- (void)initJPushWithOptions:(NSDictionary *)launchOptions {
    [JPUSHService setupWithOption:launchOptions
                        appKey:_appKey
                       channel:_channel
              apsForProduction:_isProduction
         advertisingIdentifier:nil];
    NSDictionary *remoteNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
    if(remoteNotification != nil) {
        [self handleNotification:remoteNotification type:AJPushTypeApplication];
    }
}

//初始化本地通知服务
- (void)initLocationNotification {
    NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
    [defaultCenter addObserver:self selector:@selector(networkDidReceiveMessage:) name:kJPFNetworkDidReceiveMessageNotification object:nil];
}
//自定义消息接受通知
- (void)networkDidReceiveMessage:(NSNotification *)notification {
    NSDictionary *userInfo = [notification userInfo];
    [self handleNotification:userInfo type:AJPushTypeCustomer];
}

// 通知栏进入 解析推送消息
- (void)handleNotification:(NSDictionary *)info type:(AJPushType)type {
    NSString *notificationName = kAJPushServiceInnerMessageNotification;
    //控制延迟响应时间，避免异常
    float delayTime = 0.5;
    if (type == AJPushTypeOuter) {
        [self clearBadge];
        notificationName = kAJPushServiceNoticeBarMessageNotification;
    } else if (type == AJPushTypeInner) {
        delayTime = 0.1;
        notificationName = kAJPushServiceInnerMessageNotification;
    } else if (type == AJPushTypeCustomer) {
        delayTime = 0.1;
        notificationName = kAJPushServiceCustomMessageNotification;
    } else if (type == AJPushTypeApplication) {
        [self clearBadge];
        notificationName = kAJPushServiceNoticeBarMessageNotification;
    }
    NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayTime * NSEC_PER_SEC)), queue, ^{
        [defaultCenter postNotificationName:notificationName object:self userInfo:info];
    });
}

//清除角标
- (void)clearBadge {
    [UIApplication sharedApplication].applicationIconBadgeNumber = -1;
    [JPUSHService resetBadge];
}

#pragma mark- JPUSHRegisterDelegate

// 通知栏进入 iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
    // Required
    NSDictionary * userInfo = response.notification.request.content.userInfo;
    
    if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [self handleNotification:userInfo type:AJPushTypeOuter];
    }
    completionHandler();  // 系统要求执行这个方法
}

// 应用内推送提示、透传 iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
    // Required
    NSDictionary * userInfo = notification.request.content.userInfo;

    if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [self handleNotification: userInfo type:AJPushTypeInner];
    }
    completionHandler(UNNotificationPresentationOptionSound); // 需要执行这个方法，选择是否提醒用户，有 Badge、Sound、Alert 三种类型可以选择设置
}

#pragma mark- 业务初始化请求
- (void)requestWithRegistrationId:(NSString *)registrationId {
    NSString *baseUrl = [NSString stringWithFormat:@"%@/sp/push/init", _baseUrl];
    NSURL *url_post = [NSURL URLWithString: baseUrl];
    NSMutableURLRequest *request_post = [NSMutableURLRequest
                                                requestWithURL:url_post];
    request_post.HTTPMethod = @"POST";
    [request_post setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [request_post setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    
    //获取设备信息
    NSString *brand = [AJPushDeviceInfo getBrandInfo];
    NSString *osVersion = [AJPushDeviceInfo getOSVerison];
    
    NSDictionary *reqParams = @{
        @"registrationId": registrationId,
        @"manuToken": registrationId,
        @"deviceId": registrationId,
        @"brand": brand,
        @"osVersion": osVersion,
        @"deviceType": @"5",
        @"appKey": _ajAppKey
    };
    AJDLog(@"url %@",baseUrl);
    AJDLog(@"params %@",reqParams);
    request_post.HTTPBody = [NSJSONSerialization dataWithJSONObject:reqParams options:NSJSONWritingPrettyPrinted error:nil];
    
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    config.HTTPAdditionalHeaders = @{@"Accept": @"application/json"};
    
    NSURLSession *session_post = [NSURLSession sessionWithConfiguration:config];
    
    NSURLSessionDataTask *task_post = [session_post dataTaskWithRequest:request_post completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (data) {
           NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
            AJDLog(@"data2dict:%@",dict);
        }
    }];
    [task_post resume];
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end

